STM32 USB模块讲解,详细讲解USB库通信过程(二)

您所在的位置:网站首页 usb 工作原理 STM32 USB模块讲解,详细讲解USB库通信过程(二)

STM32 USB模块讲解,详细讲解USB库通信过程(二)

2024-07-13 08:53| 来源: 网络整理| 查看: 265

今天有空,开贴讲讲,怎样配合ST 提供的库函数理解STM32F103 的USB模块,以及怎么调用这些库函数来实现基本的USB通信。题目很大,先只讲讲最简单的应用。

1 关于512字节的Packet Buffer

在STM32F103的USB模块中有一个RAM 区,称为Packet Buffer,共有512字节。 在这里插入图片描述 USB模块中有个Buffer Description Table,这个Table位于512字节的Packet Buffer中,可以在Packet Buffer 的任意位置。

USB模块提供一个寄存器USB_BTABLE来设置Buffer Description Table在PacketBuffer 的偏移地址。

在库函数中,Define 了这个偏移地址: usb_conf.h:#define BTABLE_ADDRESS (0x00) 这意味着Buffer Description Table 位于Packet Buffer 的首地址。 在这里插入图片描述 在Buffer Description Table 中的,是所用到的端点的缓存区地址寄存器和缓存区长度寄存器。所有用到的端点的这两个寄存器都位于这个Table 中。

如上所说,由于这个Table 位于Packet Buffer 的首地址。所以端点0 的发送缓冲区地址寄存器就位于Packet Buffer 的首地址,紧接的是端点0 发送缓冲区长度寄存器,接着的是端点0接收缓存区的地址寄存器,跟着是端点0 的接收缓存区的长度寄存器,等等等等,一直到最后一个端点8 的接收缓存区的长度寄存器。

每个端点的一个方向有2 个寄存器,共8 个端点16 个方向,一共32 个寄存器,每个寄存器为4 个字节,所以这个Table 一共占有128 字节。

在这里插入图片描述 在端点0 发送缓存区的地址寄存器中的值,是端点0 发送缓存区在Packet Buffer 中的偏移地址。而端点0 接收缓存区的地址寄存器中的值,是端点0 接收缓存区在Packet Buffer 中的偏移地址。

如前所说,Buffer Description Table 从理论上占有128 个字节。但对于具体的应用,不是每个应用都会用到8 个端点的16 个方向的。所以,对于那些没有用到的端点寄存器,我们可以不考虑为他们预留位置。

在ST 提供的例程中,通常这么定义: #define BTABLE_ADDRESS (0x00) /* EP0 / / rx/tx buffer base address */ #define ENDP0_RXADDR (0x18) #define ENDP0_TXADDR (0x58) 这3 句定义,意味着: 1, 端点0 的接收缓存区位于Packet Buffer 的0x18 地址。 2, 端点0 的发送缓存区位于Packet Buffer 的0x58 地址。 3, Buffer Description Table 位于Packet Buffer 的前24 字节。24 个字节意味着 应用需要使用6 个寄存器,即3 个端点。 4, 端点0 的接收缓存区长度为64 字节。

在这里插入图片描述

好了,关于这个Packet Buffer 讲解完毕。 要做一个USB应用,第一步就是要根据应用合理的分配好这个Packet Buffer。

2 使用STM32F102/103 USB函数库进行USB通信

第一步: 根据应用的需求,定义使用到的端点数量 usb_conf.h #define EP_NUM (3) 以上意味着应用需要使用到EP0,EP1 和EP2

第二步: 初始化每个使用到的端点

usb_prop.c SetEPType(ENDP2, EP_INTERRUPT); 定义端点2 为中断端点

SetEPTxAddr(ENDP2, ENDP2_TXADDR); 如果需要进行EP2 IN 通信,需要定义端点2 的发送缓存区的地址,也就是在Packet Buffer中的偏移地址

SetEPRxAddr(ENDP2, ENDP2_RXADDR); 如果需要进行EP2 OUT 通信,需要定义端点2 的接收缓存区在Packet Buffer 中的偏移地址

SetEPRxStatus(ENDP2, EP_RX_NAK); 设置端点2 的接收状态为NAK,设备将以NAK 来响应主机发起的所有OUT 通信。

SetEPTxStatus(ENDP2, EP_TX_NAK); 设置端点2 的发送状态为NAK,设备将以NAK 来响应主机发起的所有IN 通信。

第三步: 使能端点的通信对于IN 端点的使能:

UserToPMABufferCopy(Send_Buffer, ENDP2_TXADDR, 8); 拷贝用户数据到端点2 的发送缓存区

SetEPTxCount(ENDP2, 8); 设置端点2 发送数据长度

SetEPTxValid(ENDP2); 设置端点2 的发送状态为VALID

以上三句可以在应用代码的任意位置调用,一旦调用,即使能了一次USB IN通信。

USB设备将在收到主机的IN TOKEN 后,自动发送缓存区中的数据到主机,并在发送完毕后产生EP2_IN_Callback 中断,同时将端点2 的发送状态自动改为NAK。 如果需要再次进行数据传送,需要再次调用以上的三句函数。对于OUT 端点的使能:

SetEPRxValid(ENDP2); 设置端点2 的接收状态为VALID。 以上的这句函数即使能了端点2 的OUT 通信,可以在任意位置调用。

一旦调用,即使能了一次OUT 通信。USB设备将以ACK来响应主机随后的OUT 通信,并在接收数据完毕后,产生EP2_OUT_Callback 中断,同时自动将端点的接收状态改为NAK。

在EP2_OUT_Callback 中断函数中调用 USB_SIL_Read(EP2_OUT, Receive_Buffer);

可以将端点2 接收缓存区中收到的数据拷贝到用户数据区。

详细资料下载见一下链接:



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3